/*
 * BSM6.0
 *
 * Copyright 2012-2013 (C) SINODATA CO., LTD. All Rights Reserved.
 */
package com.sinodata.bsm.center.engine.fault;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;

import com.sinodata.bsm.center.cache.ResCache;
import com.sinodata.bsm.center.engine.event.EventWorkFlow;
import com.sinodata.bsm.center.service.event.EventService;
import com.sinodata.bsm.center.service.fault.TrapRuleService;
import com.sinodata.bsm.center.service.fault.TrapService;
import com.sinodata.bsm.center.util.spring.SpringContextHolder;
import com.sinodata.bsm.common.constants.EventConstants;
import com.sinodata.bsm.common.vo.Event;
import com.sinodata.bsm.common.vo.FaultTrapMsg;
import com.sinodata.bsm.common.vo.FaultTrapRule;

/**
 * <p>
 * Description: 
 * </p>
 *
 * @author wangyazhou
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-12-10 下午1:32:16          wangyazhou        1.0         To create
 * </p>
 *
 * @since 
 * @see     
 */
public class TrapDistributer {

    private static final Logger logger = Logger.getLogger(TrapDistributer.class);

    private static TrapDistributer instance;

    private final TrapService trapService = SpringContextHolder.getBean(TrapService.class);

    private final TrapRuleService trapRuleService = SpringContextHolder.getBean(TrapRuleService.class);

    private final EventService eventService = SpringContextHolder.getBean(EventService.class);

    private final ResCache resCache = SpringContextHolder.getBean(ResCache.class);

    private List<FaultTrapMsg> trapList = new ArrayList<FaultTrapMsg>();

    private static final String EVENT_TRAP = "BSM_EXT_EVENT";

    private TrapDistributer() {

    }

    /**
     * 
     * @return
     */
    public static synchronized TrapDistributer getInstance() {
        if (instance == null) {
            instance = new TrapDistributer();
            instance.new TrapPersistThread().start();
        }
        return instance;
    }

    /**
     * trap的处理
     * @param trap
     */
    public void dispose(FaultTrapMsg trap) {

        if (EVENT_TRAP.equals(trap.getGenericTrap())) {//事件TRAP 转成从外部集成的事件
            parseExtEvent(trap);
        } else { //一般TRAP  根据规则生成事件
            matchEvent(trap);
        }

        //保存trap
        trapList.add(trap);
    }

    /**
     * 
     * @param trap
     */
    private void parseExtEvent(FaultTrapMsg trap) {
        String vbs = trap.getMsg();
        if (vbs == null || vbs.length() < 1) {
            return;
        }
        Map<String, String> map = parseVbs(vbs.trim().substring(4, vbs.length() - 6));

    }

    /**
     * 把字符串把 ; 分隔
     * 每一个 = 解析为一个键值对
     * @param vbs
     * @return
     */
    private Map<String, String> parseVbs(String vbs) {
        if (vbs == null || vbs.length() < 1) {
            return null;
        }
        Map<String, String> map = new ConcurrentHashMap<String, String>();
        String[] vbAry = vbs.split("[;]");
        if (vbAry == null) {
            return null;
        }
        for (String str : vbAry) {
            String[] tmp = str.split("[=]");
            if (tmp == null) {
                continue;
            }
            map.put(tmp[0], tmp[1]);
        }
        return map;
    }

    /**
     * 产生事件  并放入事件处理流程
     * @param trap
     */
    @SuppressWarnings("unchecked")
    private void matchEvent(FaultTrapMsg trap) {

        List<Event> eventList = new ArrayList<Event>();
        List<FaultTrapRule> ruleList = trapRuleService.getTrapRuleByIp(trap.getIp());

        if (ruleList == null) {
            return;
        }

        for (FaultTrapRule rule : ruleList) {
            String filtMsg = rule.getFiltMsg();
            //过滤消息内容
            if (filtMsg != null && filtMsg.length() > 0) {
                if (!trap.getMsg().contains(filtMsg)) {
                    continue;
                }
            }
            //过滤错误状态
            String filtStatus = rule.getFiltStatus();
            if (filtStatus != null && filtStatus.length() > 0) {
                if (!filtStatus.contains(trap.getErrorStatus())) {
                    continue;
                }
            }
            //过滤TRAP的类别
            String filtGeneric = rule.getFiltGeneric();
            if (filtGeneric != null && filtGeneric.length() > 0 && (trap.getGenericTrap() != null || trap.getGenericTrap().length() > 0)) {
                if (!filtGeneric.contains(trap.getGenericTrap())) {
                    continue;
                }
            }
            //产生一个新的trap事件
            Event event = new Event();
            Date d = trap.getRecevTime();
            if (d == null) {
                d = Calendar.getInstance().getTime();
            }
            event.setOccurTime(d);
            event.setLevel(rule.getEventLevel());
            event.setResId(rule.getResId());
            event.setStatus(0);
            event.setCatalog(EventConstants.CATALOG_FAULTEVENT);
            event.setEventTypeId(rule.getEventType());
            event.setMsg(trap.toFullMsg());

            eventList.add(event);
        }
        Collections.sort(eventList, new EventSort());
        if (eventList.size() > 0) {
            logger.info("[TIP]\t由Trap生成一条事件");
            EventWorkFlow.getInstance().dispatch(eventList.get(0));
        }

    }

    /**
     * 
     * 单起一个线程用来保存trap数据
     */
    class TrapPersistThread extends Thread {
        List<FaultTrapMsg> tmpTrap = new ArrayList<FaultTrapMsg>();

        public void run() {
            while (true) {
                try {
                    Thread.sleep(60 * 1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                tmpTrap.addAll(trapList);
                trapList.clear();
                trapService.batchSave(tmpTrap);
                tmpTrap.clear();
            }
        }
    }

    @SuppressWarnings("rawtypes")
    class EventSort implements Comparator {
        public int compare(Object obj1, Object obj2) {
            Event e1 = (Event) obj1;
            Event e2 = (Event) obj2;
            if (e1.getLevel() < e2.getLevel()) {
                return 1;
            } else {
                return 0;
            }
        }
    }

}
